package club.kynb.mall.application.flow.user;

import club.kynb.mall.application.config.AuthConfig;
import club.kynb.mall.application.config.AuthProperties;
import club.kynb.mall.application.context.AuthenticationContext;
import club.kynb.mall.application.repository.AuthRepository;
import club.kynb.mall.application.constant.AuthConst;
import club.kynb.mall.application.constant.MallResultCode;
import club.kynb.mall.application.model.model.command.AuthenticationCommand;
import club.kynb.mall.application.model.model.command.PwdAuthenticationCommand;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.pizza.common.web.exception.Errors;
import org.pizza.common.web.response.CommonCode;
import org.pizza.pattern.filter.Filter;
import org.pizza.pattern.filter.FilterInvoker;
import org.pizza.util.Checker;
import org.springframework.stereotype.Component;

import java.util.Optional;

/**
 * @author kynb_club@163.com
 * @since 2020/12/18 1:48 下午
 * 检查图形验证码过滤器
 */
@Slf4j
@AllArgsConstructor
@Component
public class CheckCaptchaFilter implements Filter<AuthenticationContext> {
    private final AuthRepository authRepository;
    private final AuthProperties authProperties;

    @Override
    public void doFilter(AuthenticationContext authenticationContext, FilterInvoker<AuthenticationContext> filterInvoker) {
        log.info("检查图形验证码过滤器 start");
        AuthenticationCommand command = authenticationContext.getAuthenticationCommand();
        Optional<AuthConfig> authConfig = authProperties.get(command.getClientType());
        AuthConfig config = authConfig.orElseThrow(() -> Errors.BIZ.exception("丢失对应客户端类型的认证配置"));
        if (config.isCaptchaEnable()) {
            Checker.ifNotThrow(command instanceof PwdAuthenticationCommand
                    , (b) -> log.error("流程配置有误，当前过滤器无法处理：{}", command.getClass().getSimpleName())
                    , () -> Errors.BIZ.exception("流程配置有误，请联系开发者~"));
            PwdAuthenticationCommand pwdAuthenticationCommand = (PwdAuthenticationCommand) command;
            //参数验证 captchaKey
            Checker.ifEmptyThrow(pwdAuthenticationCommand.getCaptchaKey()
                    , () -> Errors.BIZ.exception(CommonCode.PARAM_MISS,"captchaKey"));
            //参数验证 pictureVerificationCode
            Checker.ifEmptyThrow(pwdAuthenticationCommand.getPictureVerificationCode()
                    , () -> Errors.BIZ.exception(CommonCode.PARAM_MISS,"pictureVerificationCode"));
            //查询验证码
            Optional<String> codeOptional = authRepository.getVerificationCode(getKey(pwdAuthenticationCommand.getCaptchaKey()));
            String code = codeOptional.orElseThrow(() -> Errors.BIZ.exception(MallResultCode.CODE_11002));
            //比对验证码
            Checker.ifNotThrow(pwdAuthenticationCommand.getPictureVerificationCode().equals(code)
                    , () -> Errors.BIZ.exception(MallResultCode.CODE_11003));
            authRepository.clear(getKey(pwdAuthenticationCommand.getCaptchaKey()));
        }
        log.info("检查图形验证码过滤器 end");
        filterInvoker.invoke(authenticationContext);
    }

    private String getKey(String phone) {
        return String.format("%s:%s", AuthConst.CAPTCHA, phone);
    }
}
